package com.wonders.common.parse.jaxb.config;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.validation.SchemaFactory;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import com.wonders.common.constant.CommonConstant;
import com.wonders.common.parse.jaxb.config.scaner.BaseConfigScaner;
import com.wonders.common.parse.jaxb.config.scaner.instance.XtptConfigScaner;
import com.wonders.common.parse.jaxb.entity.vo.XsdConfig;
import com.wonders.common.ws.constant.XtptConstant;
import com.wonders.framework.util.FileUtil;

/**
 * JAXB配置
 * 
 * @author WuBin
 * 
 */
@Component
public class JaxbConfig {

	private static final SchemaFactory sf = SchemaFactory
			.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

	private Logger logger = LoggerFactory.getLogger(JaxbConfig.class);

	private Map<String, Map<String, XsdConfig>> xsdConfigMap = new HashMap();

	/**
	 * 查找配置
	 * 
	 * @param xsdPath
	 *            xsd文件根目录
	 */
	public void scanConfig(String xsdPath) {
		ClassPathResource pack = new ClassPathResource(xsdPath);
		File[] files = null;
		try {
			files = pack.getFile().listFiles();
		} catch (IOException e) {
			logger.error("自动获取JAXB配置异常", e);
			return;
		}
		for (File f : files) {
			if (!f.isDirectory()) {
				continue;
			}
			BaseConfigScaner configScaner = getConfigScaner(f.getName());
			configScaner
					.scanConfig(StringUtils.join(xsdPath, "/", f.getName()));
		}
	}

	/**
	 * 获取配置查找者
	 * 
	 * @param type
	 *            类型
	 * @return 配置查找者
	 */
	private BaseConfigScaner getConfigScaner(String type) {
		if ("xtpt".equals(type)) {
			return new XtptConfigScaner(XtptConstant.VERSION_NEW);
		} else if ("xtptOld".equals(type)) {
			return new XtptConfigScaner(XtptConstant.VERSION_OLD);
		}
		return null;
	}

	/**
	 * 增加xsd配置
	 * 
	 * @param key
	 *            业务主键
	 * @param type
	 *            类型（请求/响应）
	 * @param classPath
	 *            classpath
	 * @param xsdPath
	 *            xsd文件目录
	 */
	public void addXsdConfig(String key, String type, String classPath,
			String xsdPath) {
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(type)
				|| StringUtils.isEmpty(classPath)
				|| StringUtils.isEmpty(xsdPath)) {
			return;
		}
		if (!CommonConstant.Interaction.REQ.equals(type)
				&& !CommonConstant.Interaction.RES.equals(type)) {
			return;
		}
		Map<String, XsdConfig> subMap = xsdConfigMap.get(key);
		if (subMap == null) {
			subMap = new HashMap<String, XsdConfig>();
		}
		XsdConfig xsdConfig = subMap.get(type);
		if (xsdConfig == null) {
			xsdConfig = new XsdConfig();
		}
		try {
			Class clazz = Class.forName(classPath);
			xsdConfig.setJaxbContext(JAXBContext
					.newInstance(new Class[] { Class.forName(classPath) }));
			xsdConfig.setSchema(sf.newSchema(FileUtil
					.getFileByClasspath(xsdPath)));
			xsdConfig.setClazz(clazz);
			logger.info("加载JAXB配置,key:{},type:{},class:{},xsd:{}", key, type,
					classPath, xsdPath);
		} catch (Exception e) {
			logger.error("自动获取JAXB配置异常", e);
			return;
		}
		subMap.put(type, xsdConfig);
		xsdConfigMap.put(key, subMap);
	}

	/**
	 * 获取xsd配置
	 * 
	 * @param key
	 *            业务主键
	 * @param type
	 *            类型（请求/响应）
	 * @return xsd配置
	 */
	public XsdConfig getXsdConfig(String key, String type) {
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(type)) {
			return null;
		}
		if (!CommonConstant.Interaction.REQ.equals(type)
				&& !CommonConstant.Interaction.RES.equals(type)) {
			return null;
		}
		Map<String, XsdConfig> subMap = xsdConfigMap.get(key);
		if (subMap == null) {
			return null;
		}
		return subMap.get(type);
	}

}
